import PropTypes from 'prop-types';
import React from 'react';
import { animated, config as SpringConfig, Transition } from 'react-spring';

export type ISpringConfig = 'default' | 'wobbly' | 'stiff' | 'slow' | 'molasses';

interface IFadeConfig {
  [key: string]: any;
}

export interface IFadeProps {
  active: boolean;
  config?: ISpringConfig;
  from?: React.CSSProperties;
  enter?: React.CSSProperties;
  leave?: React.CSSProperties;
  style?: React.CSSProperties;
  className?: string;
  children?: React.ReactNode;
  onClick?: () => void;
}
export class Fade extends React.PureComponent<IFadeProps> {
  public static propTypes = {
    active: PropTypes.bool,
    config: PropTypes.oneOf(['default', 'wobbly', 'stiff', 'slow', 'molasses']),
  };

  public static defaultProps = {
    active: false,
    config: 'default',
  };

  constructor(props: IFadeProps) {
    super(props);
    this.getResult = this.getResult.bind(this);
  }

  public getResult(styles: React.CSSProperties) {
    return <animated.div
      onClick={this.props.onClick}
      className={this.props.className}
      style={{
        willChange: 'opacity, transform',
        ...this.props.style,
        ...styles,
      }}>
      {this.props.children}
    </animated.div>;
  }

  public render() {
    const {
      active,
      config,
      from = { opacity: 0 },
      enter = { opacity: 1 },
      leave = { opacity: 0 },
      ...rest } = this.props;

    const fadeConfig: IFadeConfig = SpringConfig;

    const duration = !active ? { duration: 200 } : {};
    // const duration = { duration: 10000 };

    return (
      <Transition
        native
        config={{
          ...fadeConfig[`${config}`],
          precision: 0.1,
          ...duration,
        }}
        items={active}
        from={{ ...from, opacity: 0 }}
        enter={{ ...enter, opacity: 1 }}
        leave={{ ...leave, opacity: 0 }}
        {...rest}
        children={(isActive) => isActive && this.getResult}
      />
    );
  }
}
